=begin
Copyright (C) 2006  Kyle Brett <ksbrett@cc.gatech.edu>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
=end

module Sph
  module ObjectBrowser
    class BrowserView < Gtk::TreeView
      # Set to an InspectorView and this view will update the
      # subject of the inspector when the selection changes.
      attr_accessor :notify
      
      # Create an empty BrowserView.  BrowserWindow will do
      # this for you, but if you don't like BrowserWindow
      # then by all means please use this method to construct
      # your own components.  Keep in mind that if you build
      # your browser this way you'll need to create and
      # connect the inspector yourself.
      def initialize
        @store = Gtk::TreeStore.new(String, String, Object, Object)
        @notify = Array.new
        super(@store)
        addColumn(0, "Identifier")
        addColumn(1, "Info")
        signal_connect("row-expanded") do |view, iter| expand(iter) end
        selection.signal_connect("changed") do |selection| 
          selectionChanged(selection)
        end
      end
      
      private
      def selectionChanged(selection)
        @notify.each do |ob|
          if ob.respond_to? :setSubject
            ob.setSubject(selection.selected[2], selection.selected[0])
          end
        end
      end
        
      def addColumn(n, header)
        renderer = Gtk::CellRendererText.new
        col = Gtk::TreeViewColumn.new(header, renderer, :text => n)
        col.resizable = true
        append_column(col)
      end

      def expand(iter)
        0.upto iter.n_children do |i|
          fill iter.nth_child(i)
        end
      end
      
      def fill(iter)
        return if iter.nil? or iter[3]
        iter[2].instance_variables.each do |ivar|
          i = @store.append(iter)
          i[0] = ivar
          i[1] = iter[2].instance_variable_get(ivar).class.to_s
          i[2] = iter[2].instance_variable_get(ivar)
          i[3] = false
        end
        iter[3] = true
      end
      
      public
      # Add an object to the browser.  It will appear as <tt>name</tt>.
      # If you fill the browser by using BrowserWindow#fill and pass
      # a <tt>Binding</tt> the identifiers will be filled in automatically.
      def add(object, name = "[no-name]")    
        rootIter = @store.append(nil)
        rootIter[0] = name
        rootIter[1] = object.class.to_s
        rootIter[2] = object
        rootIter[3] = false
        fill rootIter
      end
    end #class BrowserView
  end #module ObjectBrowser
end #module Sph